package com.swak.fx.support;

import com.swak.exception.InvokeException;
import com.swak.fx.support.ui.UI;
import com.swak.fx.support.ui.UIPopup;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.geometry.Rectangle2D;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.stage.Window;

/**
 * 弹出框
 * 
 * @author DELL
 */
public class Popup extends AbstractPage {

	protected final UIPopup popup;

	public Popup() {
		this.popup = new UIPopup() {
			@Override
			protected Rectangle2D rectifyRectangle2D(Window window, double anchorX, double anchorY, double width,
					double heigth) {
				return Popup.this.rectifyRectangle2D(window, anchorX, anchorY, width, heigth);
			}
		};
	}

	@Override
	public void initializeParts() {
		super.initializeParts();
		this.popup.setContentNode(root);
		double width = this.root.getPrefWidth();
		double height = this.root.getPrefHeight();
		if (width <= 0) {
			width = this.root.prefWidth(-1);
		}
		if (height <= 0) {
			height = this.root.prefHeight(-1);
		}
		this.popup.prefHeightProperty().set(height);
		this.popup.prefWidthProperty().set(width);
	}

	@Override
	protected void useComputedSize() {
		this.root.setMinHeight(-1);
		this.root.setMaxHeight(-1);
		this.root.setMinWidth(-1);
		this.root.setMaxWidth(-1);
	}

	@Override
	public void setupEventHandlers() {
		super.setupEventHandlers();
	}

	@Override
	public void setupBindings() {
		super.setupBindings();
		this.popup.prefHeightProperty().bindBidirectional(this.root.prefHeightProperty());
		this.popup.prefWidthProperty().bindBidirectional(this.root.prefWidthProperty());
	}

	protected Rectangle2D rectifyRectangle2D(Window window, double anchorX, double anchorY, double width,
			double heigth) {
		return null;
	}

	public void bindMouseClickedWith(Node node) {
		node.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) -> {
			e.consume();
			Node source = (Node) e.getSource();
			this.show(source);
		});
	}

	public void bindMouseEnterWith(Node node) {
		node.addEventHandler(MouseEvent.MOUSE_ENTERED, (e) -> {
			e.consume();
			Node source = (Node) e.getSource();
			this.show(source);
		});
	}

	public void show(Node event) {
		this.show(event, 0);
	}

	public void show(Node event, double offset) {
		this.popup.show(event, offset);
	}

	public void show(Node event, double x, double y) {
		this.popup.show(event, x, y);
	}

	public void show(Window owner) {
		this.popup.show(owner, 0);
	}

	public void show(Window owner, double offset) {
		this.popup.show(owner, offset);
	}

	public final BooleanProperty animatedProperty() {
		return popup.animatedProperty();
	}

	public final ObjectProperty<UI.Locations> locationProperty() {
		return popup.locationProperty();
	}

	public final ReadOnlyBooleanProperty showingProperty() {
		return popup.showingProperty();
	}

	public final static <T extends Popup> T New(Class<T> theClass) {
		try {
			T t = theClass.getDeclaredConstructor().newInstance();
			t.init();
			return t;
		} catch (Exception e) {
			throw new InvokeException(e);
		}
	}
}